﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Collections;

namespace ConsumeAndProduceFactory
{
    public class WareHouse
    {
        private Queue queue = new Queue();
        private Object thisLock = new object();
        private Mutex mutexFlush = new Mutex();
        private bool flush = false;

        public bool Flush
        {
            get 
            {
                return flush;
            }
            set 
            {
                mutexFlush.WaitOne();
                flush = value;
                mutexFlush.ReleaseMutex();
            }
        }

        // 最佳缓冲容量
        private int maxBufferNum;
        public int MaxBufferNum
        {
            get { return maxBufferNum; }
            set { maxBufferNum = value; }
        }

        public int CurBufferNum
        {
            get { return queue.Count; }
        }

        public WareHouse()
        {
            maxBufferNum = 1000;
        }

        public WareHouse(int maxBufferNum)
        {
            this.maxBufferNum = maxBufferNum;
        }

        // 从仓库取出数据
        public List<object> fetchGoods(int num)
        {
            List<object> list = new List<object>();
            lock (thisLock)
            {
                while (queue.Count < num)
                {
                    if (flush)
                    {   // 这时候仓库应该清空所有物品了
                        num = queue.Count;
                    }
                    else
                    {
                        FactoryLog.setCusStartTime(DateTime.Now);
                        Monitor.Wait(thisLock);
                        FactoryLog.addCusMoreTime(DateTime.Now);
                    }
                }

                for (int i = 0; i < num; i++)
                {
                    list.Add(queue.Dequeue());
                    FactoryLog.incTotalConsumed();
                }
                Monitor.Pulse(thisLock);
            }

            return list;
        }

        // 将数据放入仓库
        public void pubGoods(List<object> list) 
        {
            // 如果数量超过最佳容量 这里的上限只是理论值，实际允许超过一定的数量
            lock (thisLock)
            {
                while (queue.Count + list.Count > maxBufferNum)
                {
                    // 加锁
                    FactoryLog.setProStartTime(DateTime.Now);
                    Monitor.Wait(thisLock);
                    FactoryLog.addProMoreTime(DateTime.Now);
                }
                foreach (object o in list)
                {
                    queue.Enqueue(o);
                    FactoryLog.incTotalProduced();
                }

                Monitor.Pulse(thisLock);
            }
        }

    }
}
